跳到主要内容

V8 是如何执行一段 JavaScript 代码的?

v8:将代码“翻译”成机器能读懂的机器语言

开发语言

  • 编译型语言
    1. 程序执行前,经过编译器进行编译
    2. 编译后,会保留机器能读懂的二进制文件
    3. 运行程序时,直接运行二进制文件,无需再次编译
    4. 例如:c/c++go
  • 解释型语言
    1. 在运行时,通过解释器,对程序进行 动态解释和执行
    2. 例如:pythonjavascript

AST(Abstract Syntax Tree):抽象语法书

  • babel 转化原理 es6 -> es6 ast -> es5 ast -> es5 代码
  • eslint 转化原理 code -> ast -> 根据ast的属性值进行检测
  • 生成ast
    1. 分词: 词法分析,将源码拆解成不可再分、最小单位的字符or字符串
    2. 解析: 语法分析,将分词数据,根据语法规则转为 ast

编译器和解释器

  • 编译器和解释器的工作都需要依赖于 ast
  • 编译器和解释器的最终目标都是将 ast 转化成 机器码
  • v8 根据ast 生成该段代码的执行上下文
  • 解释器
    1. 根据 ast 生成字节码
    2. 解释执行字节码
    3. 字节码需要通过解释器将其转换为机器码
  • 编译器
    1. 执行字节码过程中,若发现有热点代码,编译器就会把该段代码,编译成 高效的机器码
    2. 再次执行热点代码时,直接执行已保存的 高效的机器码

即时编译(JIT)

  • 字节码配合解释器 + 编译器
  • 解释器 Ignition 在解释执行字节码的同时,收集代码信息,当它发现某一部分代码变热了之后,TurboFan 编译器便闪亮登场,把热点的字节码转换为机器码,并把转换后的机器码保存起来,以备下次使用
  • TODO:[[即时编译(JIT)]]

参考: